/* test_crypto.c
** 
** Copyright (c) 2007, Matt Hamrick, Siobhan Murtagh & Damon Orecks
** All rights reserved.
** 
** Redistribution  and  use  in  source  and  binary  forms,  with  or  without
** modification, are permitted provided that the following conditions are met:
** 
**  * Redistributions of  source code must  retain the above  copyright notice,
**    this list of conditions and the following disclaimer.
** 
**  * Redistributions in binary form must reproduce the above copyright notice,
**    this list of conditions and the following disclaimer in the documentation
**    and/or other materials provided with the distribution.
** 
**  * Neither  the  name  of the  DangerThink  Project  nor  the names  of  its
**    contributors may be used to endorse or promote products derived from this
**    software without specific prior written permission.
** 
** THIS SOFTWARE IS PROVIDED BY  THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY  EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT  LIMITED TO, THE
** IMPLIED WARRANTIES  OF MERCHANTABILITY AND FITNESS FOR  A PARTICULAR PURPOSE
** ARE DISCLAIMED.  IN NO  EVENT SHALL THE  COPYRIGHT OWNER OR  CONTRIBUTORS BE
** LIABLE  FOR  ANY  DIRECT,   INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
** CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
** SUBSTITUTE GOODS  OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
** INTERRUPTION)  HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN
** CONTRACT,  STRICT LIABILITY,  OR  TORT (INCLUDING  NEGLIGENCE OR  OTHERWISE)
** ARISING IN ANY WAY  OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
** $Id: test_crypto.c 15 2007-05-11 05:36:17Z matthew.hamrick $
*/

#include <stdio.h>
#include <stdlib.h>
#include <CUnit/CUnit.h>
#include "test_crypto.h"
#include "stream_cipher_test.h"

static tErr app_new( tApp **app, int argc, char *argv[] );
static tErr app_test( tApp *app );
static void print_usage( int argc, char *argv[] );
static int find_in_array( char *findthis, char *inarray[], int size );

int main(int argc, char *argv[] ) {
  tErr err = APP_E_NOERR;
  tApp *app = NULL;

  do {
    if( APP_E_NOERR != ( err = app_new( &app, argc, argv ) ) ) {
      break;
    }

    if( CUE_SUCCESS != CU_initialize_registry() ) {
      err = APP_E_INIT;
      break;
    }

    if( APP_E_NOERR != (err = add_stream_cipher_suites( app ) ) ) {
      break;
    }

    if( APP_E_NOERR != (err = app_test( app ) ) ) {
      break;
    }
  } while( 0 );

  if( APP_E_INIT != err ) {
    CU_cleanup_registry();
  }

  if( APP_E_USAGE == err ) {
    print_usage( argc, argv );
  }

  return( err & 0xFF );
}

static tErr app_new( tApp **app, int argc, char *argv[] ) {
  tErr err = APP_E_NOERR;
  static char *test_types[] = {
    "automated",
    "basic",
    "console",
    "curses",
    NULL
  };

  do {
    if( NULL == app ) {
      err = APP_E_BADPARAM;
      break;
    }

    *app = malloc( sizeof( tApp ) );
    if( NULL == app ) {
      err = APP_E_ALLOC;
      break;
    }

    if( argc > 1 ) {
      switch( find_in_array( argv[1], test_types, 4 ) ) {
      case 0:
	(*app)->test_type = APP_T_AUTOMATED;
	break;

      case 1:
	(*app)->test_type = APP_T_BASIC;
	break;

      case 2:
	(*app)->test_type = APP_T_CONSOLE;
	break;

      case 3:
	(*app)->test_type = APP_T_CURSES;
	break;

      default:
	err = APP_E_USAGE;
	break;
      }
    } else {
      (*app)->test_type = APP_T_AUTOMATED;
    }
  } while( 0 );

  return( err );
}

static tErr app_test( tApp *app ) {
  tErr err = APP_E_NOERR;

  do {
    if( NULL == app ) {
      err = APP_E_BADPARAM;
      break;
    }

    switch( app->test_type ) {
    case APP_T_AUTOMATED:
      CU_automated_run_tests();
      break;

    case APP_T_BASIC:
      CU_basic_run_tests();
      break;

    case APP_T_CONSOLE:
      CU_console_run_tests();
      break;

    case APP_T_CURSES:
      /*      CU_curses_run_tests(); */
      break;

    default:
      err = APP_E_BADPARAM;
      break;
    }
  } while( 0 );

  return( err );
}

static void print_usage( int argc, char *argv[] ) {
  fprintf( stderr, "Usage: %s [testtype]\n\
where <testtype> is one of:\n\
  automated [default] - non-interactive with output to xml files\n\
  basic   - non-interactive with output to stdout\n\
  console - interactive console mode under user control\n\
  curses  - interactive with curses interface.\n", argv[0] );
}

static int find_in_array( char *findthis, char *inarray[], int size ){
  int i;

  for( i = 0; i < size; i++ ) {
    if( ! strcmp( inarray[i], findthis ) ) {
      break;
    }
  }

  if( i >= size ) {
    i = -1;
  }

  return( i );
}
